/************************************************************
* @file   gkt_rtc.c
************************************************************/

#include "gkt_dac.h"
#include "gkt_os.h"
#include "gkt_gpio.h"
#include "gkt_debug.h"
#include "gkt_driver.h"
#include "g_dac.h"

typedef struct {
	gkt_gpio_padmux_desc_s s_desc;
	gkt_dac_irq_fn s_irq;
	uint8_t play_switch;
}dac_s;
static dac_s s_dac;

void gkt_adc_irq_handler(void)
{
	if (s_dac.s_irq)
		(*s_dac.s_irq)();
}
void gkt_dac_register_irq_callback(gkt_dac_irq_fn callback)
{
	if (callback)
		s_dac.s_irq = callback;
}
void gkt_dac_start(uint32_t volume, const uint8_t *data, uint32_t data_len, int mode, uint16_t water_level, uint8_t sample_multiple)
{
	if (s_dac.play_switch == GKT_DAC_PLAY_SWITCH_CLOSE)
		return;

	gkt_unused(volume);
	G_DAC_Init(0, ENABLE, water_level, sample_multiple);
	if (data && (data_len > 0)) {
		if (mode == GKT_DAC_START_MODE_SINGLE)
			G_DAC_Out(DAC_SINGLE, (uint8_t *)data, data_len);
		else
			G_DAC_Out(DAC_CYCLE, (uint8_t *)data, data_len);
	}
	gkt_thread_sleep(1);
			//config dac output P & N
#if defined(GKT_CONFIG_DAC_OUTPUT_P_PAD_PIN)
	s_dac.s_desc.pin = GKT_CONFIG_DAC_OUTPUT_P_PAD_PIN;
	s_dac.s_desc.func = DAC_OUT;
	gkt_gpio_padmux_config(&s_dac.s_desc);
#endif
#if defined(GKT_CONFIG_DAC_OUTPUT_N_PAD_PIN)
	s_dac.s_desc.pin = GKT_CONFIG_DAC_OUTPUT_N_PAD_PIN;
	s_dac.s_desc.func = DAC_OUT;
	gkt_gpio_padmux_config(&s_dac.s_desc);
#endif
}
void gkt_dac_off(void)
{
	if (s_dac.play_switch == GKT_DAC_PLAY_SWITCH_CLOSE)
		return;

	//Set to high resistance state to prevent bursting sound
#if defined(GKT_CONFIG_DAC_OUTPUT_P_PAD_PIN)
	s_dac.s_desc.pin = GKT_CONFIG_DAC_OUTPUT_P_PAD_PIN;
	s_dac.s_desc.func = ANALOG;
	gkt_gpio_padmux_config(&s_dac.s_desc);
#endif
#if defined(GKT_CONFIG_DAC_OUTPUT_N_PAD_PIN)
	s_dac.s_desc.pin = GKT_CONFIG_DAC_OUTPUT_N_PAD_PIN;
	s_dac.s_desc.func = ANALOG;
	gkt_gpio_padmux_config(&s_dac.s_desc);
#endif

	G_DAC_Off();
}
void gkt_dac_control(gkt_dac_control_type_e type)
{
	if (s_dac.play_switch == GKT_DAC_PLAY_SWITCH_CLOSE)
		return;

	if (type == GKT_DAC_CONTROL_TYPE_FINISHED) {
		/*脉冲信号 先写1后写0*/
    DAC_DOEN |= (1 << 8);
    DAC_DOEN &= ~(1 << 8);
	}
	else if (type == GKT_DAC_CONTROL_TYPE_STOP) {
		/*MUTE*/
		DAC_DOEN |= (1 << 8);
		DAC_DOEN &= ~(0x01);
		//DAC_CTRL |= (1 << 4);
	}
}
void gkt_dac_play_switch(gkt_dac_play_switch_e type)
{
	if (type < GKT_DAC_PLAY_SWITCH_MAX)
		s_dac.play_switch = type;
}

void gkt_dac_reset_dma(uint8_t *dma_saddr, uint32_t data_len)
{
	if (s_dac.play_switch == GKT_DAC_PLAY_SWITCH_CLOSE)
		return;

	gkt_unused(dma_saddr);
	//DAC_DMA_SADDR = (uint32_t)dma_saddr;
	DAC_DMA_EADDR = DAC_DMA_SADDR + data_len;
}
int gkt_dac_init(void)
{
	gkt_irq_attr_s irq_attr;
	int retval = GKT_SUCCESS;
	static uint8_t dac_init_flag = 0;

	s_dac.s_irq = NULL;
	s_dac.play_switch = GKT_DAC_PLAY_SWITCH_OPEN;

	gkt_trace("G_DAC_Init: ...\n");	
	if (!dac_init_flag) {
		// TODO: setup irq (clear pending & enable) 
		irq_attr.flags = GKT_IRQ_F_CLEAR | GKT_IRQ_F_ENABLE;
		irq_attr.handler = gkt_adc_irq_handler;
		irq_attr.priority = GKT_IRQ_PRIORITY(GKT_ADC0_IRQ_PRIORITY);
		retval = gkt_irq_setup(GKT_ADC0_IRQ_NO, &irq_attr);
		if (retval) {
			gkt_error("gkt_dac_init: gkt_irq_setup err=%d\n", retval);
			return retval;
		}

//		adc_mutex_t = gkt_mutex_create(0);

		dac_init_flag = 1;
	}
	return retval;
}

//GKT_DEVICE_DESC_DEFINE(dac, NORMAL);

